package com.sunmouse.toolkit.fragment.media;


import android.app.ActivityManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.sunmouse.toollib.receiver.OnReceiveListener;
import com.sunmouse.toollib.utils.FileUtils;
import com.sunmouse.toollib.utils.LogUtils;
import com.sunmouse.toollib.utils.StringUtils;
import com.sunmouse.toollib.utils.ThreadPoolUtils;
import com.sunmouse.toollib.utils.ToastUtils;
import com.sunmouse.toollib.utils.system.SystemUtils;
import com.leiyun.lamelib.ringdroid.SoundFile;
import com.leiyun.lamelib.util.EncodeUtil;
import com.sunmouse.toolkit.R;
import com.sunmouse.toolkit.receiver.ProgressReceiver;
import com.sunmouse.toolkit.constant.Config;
import com.sunmouse.toolkit.constant.Value;
import com.sunmouse.toolkit.fragment.BaseFragment;
import com.sunmouse.toolkit.service.AudioService;

import java.io.File;
import java.io.IOException;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * A simple {@link Fragment} subclass.
 */
public class MediaEditFragment extends BaseFragment implements OnReceiveListener {


    @BindView(R.id.m_seek)
    SeekBar mSeek;
    @BindView(R.id.cursor_tv)
    TextView cursorTv;
    @BindView(R.id.duration_tv)
    TextView durationTv;
    @BindView(R.id.play_btn)
    ImageButton playBtn;
    @BindView(R.id.save_btn)
    ImageButton saveBtn;
    @BindView(R.id.convert_btn)
    ImageButton convertBtn;
    @BindView(R.id.control_container)
    LinearLayout controlContainer;
    @BindView(R.id.line_container)
    LinearLayout lineContainer;
    @BindView(R.id.mark_start)
    TextView markStart;
    @BindView(R.id.start_et)
    EditText startEt;
    @BindView(R.id.mark_end)
    TextView markEnd;
    @BindView(R.id.end_et)
    EditText endEt;
    Unbinder unbinder;

    private ProgressDialog mLoadingDialog;

    private ProgressReceiver mReceiver;
    private String mediaPath;
    private boolean isPlaying;
    private int mDuration;
    private int mProgress;

    private SoundFile mSoundFile;
    private File srcFile;
    private File outFile;
    private long lastUpdateTime;
    private boolean isLoading;
    private double startTime;
    private double endTime;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.activity_media_edit, container, false);
        unbinder = ButterKnife.bind(this, v);
        return v;
    }


    @Override
    public void init() {
        super.init();
//        checkMemory();
        this.mBundle = getArguments();
        mediaPath = mBundle.getString(Config.Key.MEDIA);
        srcFile = FileUtils.newFile(mediaPath);
        if (!srcFile.exists()) {
            ToastUtils.simpleToast(getActivity(), "Error: file is not existed !");
            return;
        }

        mReceiver = new ProgressReceiver();
        getActivity().registerReceiver(mReceiver, new IntentFilter(Value.Action.AUDIO_PROGRESS));
        mReceiver.setOnReceiveListener(this);

        this.playBtn.setOnClickListener(this);
        this.saveBtn.setOnClickListener(this);
        this.convertBtn.setOnClickListener(this);
        this.markStart.setOnClickListener(this);
        this.markEnd.setOnClickListener(this);


        initDialog(ProgressDialog.STYLE_HORIZONTAL, "Loading...");
        showProgress(true);
        isLoading = true;
        //read file in background
        readFile();
    }

    /**
     * read media file
     */
    private void readFile() {
        ThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {

                try {
                    String[] components = mediaPath.split("\\.");
                    if (components.length < 2) {
                        mHandler.sendEmptyMessage(Value.Status.DISMISS);
                        return;
                    }
                    mSoundFile = SoundFile.create(srcFile.getAbsolutePath(), new LoadingFileHandle());
                } catch (IOException e) {
                    e.printStackTrace();
                    mHandler.sendEmptyMessage(Value.Status.DISMISS);
                } catch (SoundFile.InvalidInputException e) {
                    e.printStackTrace();
                    mHandler.sendEmptyMessage(Value.Status.DISMISS);
                }
                mHandler.sendEmptyMessage(Value.Status.DISMISS);
            }
        });
    }

    /**
     *
     */
    private void checkMemory() {
        ActivityManager am = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE);
        int memory = am.getMemoryClass();
        LogUtils.v("----large=" + am.getLargeMemoryClass() + "---normal=" + memory);
    }

    /**
     * play media
     */
    private void playMedia() {
        if (!SystemUtils.isServiceWork(getActivity(), AudioService.class.getSimpleName())) {
            mIntent = new Intent(getActivity(), AudioService.class);
            mIntent.setAction(Value.Action.AUDIO);
            mIntent.putExtra(Config.Key.MEDIA, mediaPath);
            getActivity().startService(mIntent);
            return;
        }

        sendCommand(isPlaying ? Value.Control.PAUSE : Value.Control.PLAY);
    }


    /**
     * init progress dialog
     *
     * @param style
     * @param title
     */
    public void initDialog(int style, String title) {
        super.initDialog();
        mLoadingDialog = new ProgressDialog(getActivity());
        mLoadingDialog.setProgressStyle(style);
        mLoadingDialog.setTitle(title);
        mLoadingDialog.setCancelable(true);
        mLoadingDialog.setOnCancelListener(mOnCancelListener);
    }


    /**
     * on cancel listener
     */
    private DialogInterface.OnCancelListener mOnCancelListener = new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            isLoading = false;
        }
    };

    /**
     * send command
     *
     * @param command
     */
    private void sendCommand(int command) {
        mIntent = new Intent().setAction(Value.Action.AUDIO_COMMAND);
        mIntent.putExtra(Config.Key.CONTROL, command);
        getActivity().sendBroadcast(mIntent);
    }

    /**
     * set progress visibility
     *
     * @param isShowing
     */
    private void showProgress(boolean isShowing) {
        if (isShowing && !mLoadingDialog.isShowing()) {
            mLoadingDialog.show();
            return;
        }
        mLoadingDialog.dismiss();
        isLoading = false;
    }


    @Override
    public void onHandleMessage(Message msg) {
        super.onHandleMessage(msg);
        if (msg.what == Value.Status.SHOWING) {

        } else if (msg.what == Value.Status.DISMISS) {
            showProgress(false);
        } else if (msg.what == Value.Status.SUCCESS) {
            showProgress(false);
            ToastUtils.simpleToast(getActivity(), "cut successfully !");
        } else if (msg.what == Value.Status.FAILURE) {
            showProgress(false);
            ToastUtils.simpleToast(getActivity(), "cut unsuccessfully !");
        } else if (msg.what == Value.Status.CONVERT) {
            ToastUtils.simpleToast(getActivity(), "convertFromWav successfully !");
            showProgress(false);
        }
    }

    /**
     * convertFromWav file to Mp3
     */
    private void convertToMp3() {
        initDialog(ProgressDialog.STYLE_SPINNER, "converting...");
        mLoadingDialog.setIndeterminate(true);
        showProgress(true);
        ThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
//                VoiceConvert mConvert = new VoiceConvert();
                EncodeUtil mEncodeUtil = new EncodeUtil();
                File mp3File = FileUtils.newFile(FileUtils.getStoragePath(), "my_sample.mp3");
                if (!mp3File.exists()) {
                    LogUtils.v("----create file unsuccessfully");
                    return;
                }
//
//                String[] spl = outFile.getName().split("\\.");
//                if (spl[1].equals("m4a")) {
//                    mEncodeUtil.convertFromM4a(outFile.getAbsolutePath(), mp3File.getAbsolutePath());
//                    mHandler.sendEmptyMessage(Value.Status.CONVERT);
//                    return;
//                }
                if (outFile == null)
                    outFile = FileUtils.newFile(FileUtils.getStoragePath(), "sample-1.wav");
                mEncodeUtil.setOnProgressListener(new EncodeUtil.OnProgressListener() {
                    @Override
                    public void onProgress(int progress) {
                        LogUtils.v("-----------pro=" + progress);
                    }
                });
                mEncodeUtil.convertFromWav(outFile.getAbsolutePath(), mp3File.getAbsolutePath());

//                if (resultStatus) {
//                    mHandler.sendEmptyMessage(Value.Status.SAVED);
//                    return;
//                }
                mHandler.sendEmptyMessage(Value.Status.CONVERT);
            }
        });
    }

    @Override
    public void onClick(View v) {
        super.onClick(v);
        switch (v.getId()) {
            case R.id.play_btn:
                playMedia();
                break;
            case R.id.save_btn:
                saveMedia();
                break;
            case R.id.convert_btn:
//                outFile = FileUtils.newFile(FileUtils.getStoragePath(), "sample-1.wav");
                convertToMp3();
                break;
            case R.id.mark_start:
                startEt.setText(StringUtils.parseTime(mProgress));
                break;
            case R.id.mark_end:
                endEt.setText(StringUtils.parseTime(mProgress));
                break;
        }
    }

    /**
     * save media in sub thread
     */
    private void saveMedia() {
        sendCommand(Value.Control.PAUSE);
        startTime = StringUtils.parseTime(startEt.getText().toString()) / 1000.f;
        endTime = StringUtils.parseTime(endEt.getText().toString()) / 1000.f;
        LogUtils.v("------st=" + startTime + "-----et=" + endTime);
        initDialog(ProgressDialog.STYLE_SPINNER, "Saving");
        mLoadingDialog.setIndeterminate(true);
        isLoading = true;
        showProgress(true);
        ThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                if (mSoundFile == null) return;
                //save as wav
                outFile = FileUtils.newFile(FileUtils.getStoragePath(), "sample-1.wav");
                try {
                    mSoundFile.writeWAVFile(outFile, startTime, endTime);
                } catch (Exception e) {
                    LogUtils.v("------cannot be edited");
                    e.printStackTrace();
                    mHandler.sendEmptyMessage(Value.Status.FAILURE);

                }
                mHandler.sendEmptyMessage(Value.Status.SUCCESS);
            }
        });
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null || !intent.getAction().equals(Value.Action.AUDIO_PROGRESS)) return;
        //progress bar
        mDuration = intent.getIntExtra(Config.Key.DURATION, -1);
        mProgress = intent.getIntExtra(Config.Key.PROGRESS, -1);
        LogUtils.v("-----------------" + mProgress);
        if (mDuration != -1) {
            durationTv.setText(StringUtils.parseTime(mDuration));
        }

        if (mProgress != -1) {
            cursorTv.setText(StringUtils.parseTime(mProgress));

            mSeek.setProgress(mProgress * 100 / mDuration);

        }

        /*
        playing status
         */
        int status = intent.getIntExtra(Config.Key.STATUS, -1);
        if (status == -1) return;

        switch (status) {
            case Value.Status.PLAYING:
                ToastUtils.simpleToast(getActivity(), "----start playing----");
                isPlaying = true;
                break;
            default:
                isPlaying = false;
                ToastUtils.simpleToast(getActivity(), "----stop playing----");
                break;

        }

        updatePlayUI();
    }

    /**
     * update play ui   (icon e.i)
     */
    private void updatePlayUI() {
        if (isPlaying) {
            this.playBtn.setImageResource(android.R.drawable.ic_media_pause);
            this.playBtn.setContentDescription("pause");
        } else {
            this.playBtn.setImageResource(android.R.drawable.ic_media_play);
            this.playBtn.setContentDescription("pause");
        }
    }

    /**
     * handle loading progress
     */
    class LoadingFileHandle implements SoundFile.ProgressListener {
        @Override
        public boolean reportProgress(double fractionComplete) {
            long currentTime = System.nanoTime();
            if (currentTime - lastUpdateTime > 100) {
                mLoadingDialog.setProgress((int) (mLoadingDialog.getMax() * fractionComplete));
                lastUpdateTime = currentTime;
            }
            return isLoading;
        }
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
}
